<?php

namespace App\Http\Services;

use Exception;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Redis;
use App\Http\Model\Hint;
use App\Http\Model\User;
use App\Http\Model\Equip;
use App\Http\Model\FinanceUserWallet;
use App\Http\Model\FinanceDiamond;

class EquipServices extends CommonServices
{
    protected $equipModel;
    protected $userModel;
    protected $userWalletModel;
    protected $financeDiamondModel;

    public function __construct()
    {
        parent::__construct();

        $this->user = new User();
        $this->equipModel = new Equip();
        $this->userWalletModel = new FinanceUserWallet();
        $this->financeDiamondModel = new FinanceDiamond();

    }

    /**
     * 给指定用户发装备
     */
    public function sendEquipToUser($equipList=[]){
        $code = Hint::SUCCESS;
        $msg = '';
        $data = [];
        do {
            if(empty($equipList)) {
                $code = Hint::PARAM_ERROR;
                break;
            }
            //判读装备是否存在
            $equipIds = array_unique(array_column($equipList, 'equip_id'));
            $list = $this->equipModel->getEquipByIds($equipIds);
            if(empty($list) || count($equipIds)!=count($list)) {
                $code = Hint::PARAM_ERROR;
                $msg = '装备信息查询失败';
                break;
            }

            //写入新数据
            $flag = 0;
            foreach($equipList as $val) {
                try {
                    $id = $this->equipModel->createUserEquip($val['user_id'], $val['equip_id']);
                    if(!$id) {
                        $flag = 1;
                    }
                } catch (\Exception $e) {
                    $flag = 1;
                }
            }
            if($flag) {
                $code = Hint::ERR_SYS_FAIL;
                $msg = '添加用户装备失败';
                break;
            }

            //更新用户装备数量
            DB::beginTransaction();
            try {
                foreach($equipList as $val) {
                    $this->equipModel->inc($val['user_id'], $val['equip_id'], $val['num'], $val['equip_type'], $val['data_id']);
                }
                DB::commit();
            } catch (\Exception $e) {
                DB::rollBack();

                $code = Hint::ERR_SYS_FAIL;
                $msg = '修改用户装备数量失败';
                break;
            }

        } while (false);

        return compact('code', 'msg', 'data');
    }

    /**
     * 获取装备类型
     */
    public function getEquipType(){
        $data = [];
        do {
            $list = $this->equipModel->getEquipType();

            $data['list'] = $list;

        } while (false);

        return $data;
    }

    /**
     * 获取用户正在使用的装备
     */
    public function getUserUseEquip($userId){
        $data = [];
        do {
            if(empty($userId)) {
                break;
            }
            $list = $this->equipModel->getUserEquipByUserId($userId);

            $data['userEquip'] = $list;

        } while (false);

        return $data;
    }

    /**
     * 获取用户拥有的装备列表
     */
    public function getUserHasEquipList($page, $limit, $userId, $equipType){
        $data = [];
        do {
            if(empty($userId)) {
                break;
            }
            $list = $this->equipModel->getUserHasEquipList($page, $limit, $userId, $equipType);

            $data['list'] = $list;

        } while (false);

        return $data;
    }

    /**
     * 用户装备装备
     */
    public function userUseEquip($userId, $equipIds=[]){
        $code = Hint::SUCCESS;
        $msg = '';
        $data = [];

        do {
            if(empty($userId)) {
                $code = Hint::PARAM_ERROR;
                break;
            }
            $cacheKey = 'EQUIP:USERUSE:'.$userId;
            if (!redis_lock($cacheKey, 5)) {
                $code = Hint::SAME_TIME_NOT_REPEAT;
                break;
            }
            //所有装备都脱掉
            $this->equipModel->updateUseUnuseAllEquip($userId);

            //穿指定装备
            if(!empty($equipIds)) {
                //获取所有装备数据
                $equipList = $this->equipModel->getEquipAll();

                foreach($equipIds as $equipId) {
                    //根据装备ID获取用户装备
                    $userEquip = $this->equipModel->getUserEquipByUserIdEquipId($userId, $equipId);
                    if(empty($userEquip) || $userEquip['num']<1) {
                        continue;
                    }
                    //穿戴
                    $this->equipModel->updateUseUseEquip($userId, $equipId);
                }
            }
            redis_unlock($cacheKey);

        } while (false);

        return compact('code', 'msg', 'data');
    }

    /**
     * 获取装备货架列表
     */
    public function getEquipShelveList($userId, $equipType){
        $data = [];
        do {
            //获取用户性别
            $userInfo = $this->user->get_user($userId);
            $gender = $userInfo['gender'];

            $list = $this->equipModel->getEquipShelveList($equipType);
            $listEx = [];
            foreach($list as $val) {
                if($val['equip_sex'] == $gender) {
                    $listEx[] = $val;
                }
            }
            $data['list'] = $listEx;

        } while (false);

        return $data;
    }

    /**
     * 用户装备装备
     */
    public function buyEquipShelve($userId, $shelves=[], $ifUse=0){
        $code = Hint::SUCCESS;
        $msg = '';
        $data = [];

        do {
            if(empty($userId)) {
                $code = Hint::LOGIN_OUT;
                break;
            }
            if(empty($shelves)) {
                $code = Hint::PARAM_ERROR;
                break;
            }
            $shelveList = $this->equipModel->getEquipShelveList();
            $shelveList = array_column($shelveList, null, 'shelve_id');

            //计算金额
            $flag = 0;
            $needNumDiamond = 0;
            $equipList = [];
            $equipIds = [];
            foreach($shelves as $val) {
                if(empty($shelveList[$val['shelve_id']])) {
                    $flag = 1;
                }else{
                    if($shelveList[$val['shelve_id']]['price_type'] != 1) {
                        $flag = 1;
                    }else{
                        $needNumDiamond = $needNumDiamond + $val['num']*$shelveList[$val['shelve_id']]['price'];
                    }
                    $equipList[] = [
                        'equip_id' => $shelveList[$val['shelve_id']]['equip_id'],
                        'num' => $val['num'],
                        'data_id' => $val['num']*$shelveList[$val['shelve_id']]['price'],
                    ];
                    $equipIds[$shelveList[$val['shelve_id']]['equip_type']] = $shelveList[$val['shelve_id']]['equip_id'];
                    //添加用户装备
                    try {
                        $id = $this->equipModel->createUserEquip($userId, $shelveList[$val['shelve_id']]['equip_id']);
                        if(!$id) {
                            $flag = 1;
                        }
                    } catch (\Exception $e) {
                        $flag = 1;
                    }
                }
            }
            if($flag == 1) {
                $code = Hint::PARAM_ERROR;
                $msg = '购买请求装备信息异常';
                break;
            }
            //用户账户
            $wallet = $this->userWalletModel->get_wallet($userId);
            if($wallet['diamond_balance'] < $needNumDiamond) {
                $code = Hint::DIAMOND_NOT_ENOUGH;
                break;
            }
            $config = config('pay');
            $diamond_desc = $config['wallet_change_desc']['diamond_buy_equip'];

            //锁
            $cacheKey = 'EQUIP:USERBUYSHELVE:'.$userId;
            if (!redis_lock($cacheKey, 5)) {
                $code = Hint::SAME_TIME_NOT_REPEAT;
                break;
            }

            DB::beginTransaction();
            try {
                //钻石
                $this->financeDiamondModel->inc($userId, 0, 0, 76, 0-abs($needNumDiamond), $diamond_desc);

                //更新用户装备数量
                foreach($equipList as $val) {
                    $this->equipModel->inc($userId, $val['equip_id'], $val['num'], 1, $val['data_id']);
                }

                DB::commit();
            } catch (\Exception $e) {
                DB::rollBack();

                write_log('error_equip', 'buyEquipShelve', [$userId, $shelves, 'msg'=>$e->getMessage(), 'line'=>$e->getLine()]);
                $code = Hint::ERR_FAIL;
                break;
            }
            redis_unlock($cacheKey);

            //穿装备
            if($ifUse==1 && !empty($equipIds)) {
                if(isset($equipIds[8])) {
                    $equipIds = [$equipIds[8]];
                }else{
                    $equipIds = array_values($equipIds);
                }
                $this->userUseEquip($userId, $equipIds);
            }

        } while (false);

        return compact('code', 'msg', 'data');
    }

    /**
     * 编辑装备
     */
    public function editEquip($equipId, $params=[]){
        $code = Hint::SUCCESS;
        $msg = '';
        $data = [];
        do {
            if(empty($equipId) || empty($params)) {
                break;
            }
            $res = $this->equipModel->updateEquip($equipId, $params);

        } while (false);

        return compact('code', 'msg', 'data');
    }

    /**
     * 装备货架新增
     */
    public function addEquipShelve($params=[]){
        $code = Hint::SUCCESS;
        $msg = '';
        $data = [];
        do {
            //装备信息
            $info = $this->equipModel->getEquipById($params['equip_id']);
            if(empty($info)) {
                $code = Hint::PARAM_ERROR;
                $msg = '获取装备信息失败';
                break;
            }
            //是否存在
            $info = $this->equipModel->getEquipShelveByEquipId($params['equip_id']);
            if(!empty($info)) {
                $code = Hint::PARAM_ERROR;
                $msg = '装备已添加货架,不可重复添加';
                break;
            }

            $res = $this->equipModel->addEquipShelve($params);

        } while (false);

        return compact('code', 'msg', 'data');
    }

    /**
     * 装备货架编辑
     */
    public function editEquipShelve($shelveId, $params=[]){
        $code = Hint::SUCCESS;
        $msg = '';
        $data = [];
        do {
            if(empty($shelveId) || empty($params)) {
                break;
            }
            $res = $this->equipModel->editEquipShelve($shelveId, $params);

        } while (false);

        return compact('code', 'msg', 'data');
    }

    /**
     * 装备货架删除
     */
    public function delEquipShelve($shelveId){
        $code = Hint::SUCCESS;
        $msg = '';
        $data = [];
        do {
            if(empty($shelveId)) {
                break;
            }
            $params = ['is_delete'=>1];
            $res = $this->equipModel->editEquipShelve($shelveId, $params);

        } while (false);

        return compact('code', 'msg', 'data');
    }

    /**
     * 编辑装备类型
     */
    public function editEquipType($id, $params=[]){
        $code = Hint::SUCCESS;
        $msg = '';
        $data = [];
        do {
            if(empty($id) || empty($params)) {
                break;
            }
            $res = $this->equipModel->editEquipType($id, $params);

        } while (false);

        return compact('code', 'msg', 'data');
    }


}